闲话 22.12.11

闲话

我发现我浏览器抽风所以我随时保存

上面那个是我改标题为[闲话+日期]前的暂标题/占位符
以前的暂标题就很暂(
有好奇的读者可以猜一猜

就是 今天看到了……忘记了 但是点进了 ARC106D
然后就浅做了一下

又是荒废(?)网络流的一天呢(
推流jjdw的鲜花

感觉这两天下载上传资料电脑卡顿程度直线上升
《感觉是该清灰了》
《其实我的浏览器经常有黑屏啦倒是 我也不知道为什么》
《点开我的浏览器的时候有一定的概率》
《得按照一定的顺序 : (》
《这不是挺好的嘛》
妈妈生的(即答

杂题

ARC106D

给定长度为 n 的序列 a,以及一个整数 k

对于每个 1xk,求出如下式子的值:

l=1n1r=l+1n(al+ar)x

答案对 998244353 取模。

2n2×105, 1k300, 1ai108

不难发现,

l=1nr=1n(al+ar)x=2l=1n1r=l+1n(al+ar)x+l=1n(al+al)x

于是可以计算

l=1nr=1n(al+ar)x

减去

l=1n(al+al)x

后除二就是答案。

根据二项式定理,可以得到

l=1nr=1n(al+ar)x= l=1nr=1ni=1x(xi)aliarxi= i=1xl=1nr=1nalii!x!arxi(xi)!= i=1xx!(l=1nalii!)(r=1narxi(xi)!)

由于 x 的范围小,可以支持 O(k2) 的复杂度,我们可以枚举 xi 合并答案。

对每个 1mk 预处理

l=1nalmm!

即可做到 O(k2) 合并答案。合并答案也可应用卷积,但复杂度瓶颈不在这里。

朴素合并的总时间复杂度为 O(nk+k2)

code
#include <bits/stdc++.h>
using namespace std;
template <typename T> void get(T & x) {
	x = 0; char ch = getchar(); bool f = false; while (ch < '0' or ch > '9') f = f or ch == '-', ch = getchar();
	while ('0' <= ch and ch <= '9') x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); f && (x = -x); 
} template <typename T, typename ... Args> void get(T & a, Args & ... b) { get(a); get(b...); }
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
const int N = 4e5 + 10;
int n, k, sum[305], a[N], v[305];

signed main() {
	get(n, k); rep(i,1,n) get(a[i]);
    init_fac(305);
    v[0] = n;
    rep(j,1,n) {
        int t1 = 1, t2 = 1;
        rep(i,1,k) {
            t1 = mul(t1, a[j]), t2 = mul(t2, 2 * a[j]);
            v[i] = add(v[i], mul(t1, ifc[i]));
            sum[i] = add(sum[i], t2);
        }
    }
    rep(x,1,k) {
        int ans = 0;
        rep(i,0,x) ans = add(ans, mul(v[i], v[x - i]));
        ans = mul(ans, fac[x]);
        ans = sub(ans, sum[x]);
        cout << mul(ans, inv2) << '\n';
    }
}



ARC106E

你有 n 个朋友,他们会来你家玩,第 i 个人 1Ai 天来玩,然后 Ai+12Ai 天不来,然后 2Ai+13Ai 天又会来,以此类推。

每天你会选一个来玩的人,给他颁个奖,如果没人来玩,你就不颁奖。你要给每个人都颁 K 个奖,问至少需要多少天。

1n18, 1k105, 1Ai105

二分答案转化为判定。

判定的话考虑建二分图。假设当前的天数是 t,左部点是 t 天,右部点是 n×k 个人对应的奖。每个人和他会来玩的那些天连边,流就是奖。最后看是不是能流满即可。
我们发现,这就是在寻找二分图完全匹配。由于人数少,考虑把一天来的人压成状态。施 Hall 定理,我们只需要考虑每个状态 i 能和多少天连边,也就是有多少天对应的状态和它有交。假设这个值是 s,则该状态满足要求当且仅当 spopcount(i)×k。所有状态满足要求则 t 满足要求。
考虑求有多少天的状态是状态 i 的补集的子集,再用 t 减去就是状态 is。应用 SOS DP 可以得到答案。

二分边界?容易发现 2nk 一定满足要求。
总时间复杂度 O(n2nlog(nk))

code
#include <bits/stdc++.h>
using namespace std; using pii = pair<int,int>; using vi = vector<int>; using vp = vector<pii>; using ll = long long; 
using ull = unsigned long long; using db = double; using ld = long double; using lll = __int128_t;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
template <typename T> T rand(T l, T r) { return uniform_int_distribution<T>(l, r)(rnd); }
template <typename T> void get(T & x) {
	x = 0; char ch = getchar(); bool f = false; while (ch < '0' or ch > '9') f = f or ch == '-', ch = getchar();
	while ('0' <= ch and ch <= '9') x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); f && (x = -x); 
} template <typename T, typename ... Args> void get(T & a, Args & ... b) { get(a); get(b...); }
#define iot ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
template <typename T1, typename T2> T1 min(T1 a, T2 b) { return a < b ? a : b; }
template <typename T1, typename T2> T1 max(T1 a, T2 b) { return a > b ? a : b; }
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define ufile(x) 
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
#define Aster(i, s) for (int i = head[s], v; i; i = e[i].next)
#define all(s) s.begin(), s.end()
#define pcnt(x) __builtin_popcount(x)
#define eb emplace_back
#define pb pop_back
#define em emplace
const int N = 1e7 + 10;
const int inf = 0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fll;
int n, k, m, a[N], f[N];

int g[N];
bool check(int d) {
    rep(i,0,(1<<n)-1) g[i] = 0;
    rep(i,1,d) g[f[i]] ++;
    rep(i,0,n-1) rep(j,0,(1<<n)-1) {
        if (!(j >> i & 1)) 
            g[j | (1 << i)] += g[j];
    } 
    rep(i,0,(1<<n)-1) if (d - g[(1 << n) - 1 - i] < pcnt(i) * k) return false;
    return true;
}

signed main() {
	get(n, k); rep(i,1,n) get(a[i]);
    m = 2 * n * k;
    rep(i,1,m) rep(j,1,n) if (((i + a[j] - 1) / a[j]) & 1) f[i] |= 1 << j - 1;
    int l = 1, r = m, mid;
    while (l <= r) {
        mid = l + r >> 1;
        if (check(mid)) r = mid - 1;
        else l = mid + 1;
    }
    cout << r + 1 << '\n';
}



ARC106F

n 个点,每个点有 ai 个孔,每次可以选择两个不同点,连接两个未被连接过的孔,有多少中方案使得最后形成一棵树。
答案对 998244353 取模。

2n2×105, 1di998244352

Solution 1 生成法计数

官方题解采用的方法。

首先可以发现只有当 di2(n1) 时有解。

随后考虑如何生成所有可能的方案。我们称一个联通的子图为一个分量,最开始有 n 个分量。
最开始在每个分量上选取一个特殊点。随后按如下方式操作:

  • 将分量数量减小到 2
  1. 选择一个非特殊点 a
  2. 选择一个不与点 a 位于同一分量中的特殊点 b
  3. 连接 a,b。新分量的特殊点是其中一个距离 a,b 最近的可连边的点。
  • 连接最后的两个分量上的特殊点。

最开始选择特殊点的方案数是 i=1ndi。记 S=i=1ndi,第 i 次选择时非特殊点数量为 (Sn(i1)) 个,能连接的联通块数是 (ni) 个,自然导出了方案数

i=1ndi×i=1n2(ni)(Sn(i1))=i=1ndi×(n1)!×i=0n3(Sni)

考虑生成方式,我们发现同一棵树会以不同的加边顺序在答案中被统计 (n1)! 次,因此最终答案为

i=1ndi×i=0n3(Sni)

Solution 2 生成函数

首先固定每个点 i 在最终生成的树中的度数 ri

由 prufer 序列导出结论,一棵满足上述度数条件的树的计数是

(n2)!i=1n(ri1)!

证明考虑计数 prufer 序列,元素 i 在其中出现了 ri1 次。

每个点在连接时是有序的,因此在度数固定为 r 的情况下,贡献是

(n2)!i=1n(ri1)!×i=1nAdiri

可以发现 ri=2(n1)。因此不妨从卷积的角度入手,枚举 ri 的取值。

发现 (n2)! 是所有可能都会贡献的,因此只需要生成剩余部分即可。

Fi(x) 为点 i 对答案的贡献的生成函数,有

Fi(x)=k=0Adik(k1)!xk=k=0(dik)k xk=dik=1(di1k1) xk=dixk=0(di1k) xk=dix(1+x)di1

可以写出答案

(n2)!×[x2(n1)]i=1nFi(x)= (n2)!×[x2(n1)]i=1ndix(1+x)di1= (n2)!×i=1ndi×[xn2]i=1n(1+x)di1

S=i=1ndi,有

(n2)!×i=1ndi×[xn2]i=1n(1+x)di1= (n2)!×i=1ndi×[xn2](1+x)Sn= (n2)!×i=1ndi×(Snn2)= i=1ndi×(Sn)n2_= i=1ndi×i=0n3(Sni)

两种做法得到了相同的答案。
总时间复杂度为 O(n)

个人认为 Solution 2 更简单易懂一些。

code
#include <bits/stdc++.h>
using namespace std; 
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
const int mod = 998244353;
int n, prod = 1, sum, tmp;
signed main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cin >> n; 
    rep(i,1,n) {
        cin >> tmp; 
        prod = 1ll * prod * tmp % mod, sum += tmp;
        if (sum >= mod) sum -= mod;
    }
    rep(i,0,n-3) prod = 1ll * prod * (sum - n - i) % mod;
    cout << prod << '\n';
}
posted @   joke3579  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示